Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit f06c2e7b968c4169dfb1bec524f91bb8b6426557


Parents : 2dcc759
Author : Mark Qvist <bc7291552be7a58f361522990465165c>
Signature : T66BB85Valid, signed by author
Date : 2026-07-16T12:24:47+02:00

Added incoming messages status

Changes

3 files changed, 75 insertions(+), 7 deletions(-)

M sbapp/main.py +59 -2

Diff

diff --git a/sbapp/main.py b/sbapp/main.py
index cb58b502..cea61bd0 100644
--- a/sbapp/main.py
+++ b/sbapp/main.py
@@ -605,6 +605,7 @@ class SidebandApp(MDApp):
self.resume_event_scheduler = None
self.connectivity_updater = None
+ self.incoming_messages_updater = None
self.last_map_update = 0
self.last_telemetry_received = 0
self.repository_url = None
@@ -1567,9 +1568,9 @@ class SidebandApp(MDApp):
self.message_area_detect()
elif self.root.ids.screen_manager.current == "conversations_screen":
+ if self.conversations_view and self.conversations_view.ready: self.conversations_view.update_incoming_status()
if self.sideband.getstate("app.flags.unread_conversations", allow_cache=True):
- if self.conversations_view != None:
- self.conversations_view.update()
+ if self.conversations_view != None: self.conversations_view.update()
if self.sideband.getstate("app.flags.lxmf_sync_dialog_open", allow_cache=True) and self.sync_dialog != None:
state = self.sideband.message_router.propagation_transfer_state
@@ -2980,6 +2981,62 @@ class SidebandApp(MDApp):
self.sideband.setstate("wants.clear_notifications", True)
Clock.schedule_once(cb, 0.10)
+ def get_incoming_messages_text(self):
+ try:
+ if not self.sideband.message_router: return "LXMF router starting..."
+ else:
+ inbound_count = self.sideband.message_router.inbound_count()
+ if inbound_count == 0: return "No incoming messages"
+ else:
+ inbound = self.sideband.message_router.inbound_resources()
+ if len(inbound) == 0: return "No incoming messages"
+ else:
+ text = f"[b]Receiving {inbound_count} message resource{'s' if inbound_count != 1 else ''}[/b]"
+ size = 0
+ prgr = 0
+ for r in inbound:
+ size += r.get_data_size()
+ prgr += r.get_progress()
+
+ prgr = prgr/len(inbound)
+ text += f"\nTotal size : {RNS.prettysize(size)}"
+ text += f"\nProgress : {round(prgr*100, 2)}%"
+ return text
+
+ except Exception as e:
+ RNS.log(f"Error getting incoming messages information: {e}", RNS.LOG_ERROR)
+ return "Error getting incoming messages information"
+
+ def cancel_incoming_action(self, sender=None):
+ RNS.log(f"Cancelling all inbound message resources", RNS.LOG_NOTICE)
+ self.sideband.message_router.cancel_all_inbound()
+
+ def incoming_messages_action(self, sender=None):
+ hs = dp(22)
+ ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18))
+ cancel_button = MDRectangleFlatButton(text="Cancel Incoming",font_size=dp(18), theme_text_color="Custom", line_color=self.color_reject, text_color=self.color_reject)
+ dialog = MDDialog(
+ title="Incoming Messages",
+ text=str(self.get_incoming_messages_text()),
+ buttons=[cancel_button, ok_button])
+
+ def im_updater(dt): dialog.text = str(self.get_incoming_messages_text())
+
+ def dl_ok(s):
+ dialog.dismiss()
+ if self.incoming_messages_updater != None: self.incoming_messages_updater.cancel()
+
+ def cb_cancel(sender): self.cancel_incoming_action()
+
+ ok_button.bind(on_release=dl_ok)
+ cancel_button.bind(on_release=cb_cancel)
+ dialog.open()
+
+ if self.incoming_messages_updater != None:
+ self.incoming_messages_updater.cancel()
+
+ self.incoming_messages_updater = Clock.schedule_interval(im_updater, 1.0)
+
def get_connectivity_text(self):
try:
connectivity_status = ""

diff --git a/sbapp/sideband/cli/cmd_system.py b/sbapp/sideband/cli/cmd_system.py
index 2bad26ca..8406168b 100644
--- a/sbapp/sideband/cli/cmd_system.py
+++ b/sbapp/sideband/cli/cmd_system.py
@@ -31,8 +31,9 @@ def _cmd_raw(args, sideband, ctx):
try:
result = eval(expr)
+ # result = exec(expr)
if result is not None: return repr(result)
- return "None"
+ else: return "None"
except Exception as e: return f"Error: {e}"
def _cmd_log(args, sideband, ctx):

diff --git a/sbapp/ui/conversations.py b/sbapp/ui/conversations.py
index 74a9ca2c..fd2d66b4 100644
--- a/sbapp/ui/conversations.py
+++ b/sbapp/ui/conversations.py
@@ -254,6 +254,7 @@ class Conversations():
self.added_item_dests = []
self.list = None
self.conversation_list = None
+ self.ready = False
self.ids = None
if not self.app.root.ids.screen_manager.has_screen("conversations_screen"):
@@ -269,24 +270,32 @@ class Conversations():
self.clear_telemetry_dialog = None
self.update()
+ self.ready = True
def update(self):
self.context_dests = self.app.sideband.list_conversations(conversations=self.app.include_conversations, objects=self.app.include_objects)
view_title = "Conversations"
if self.app.include_conversations:
- if self.app.include_objects:
- view_title = "Conversations & Objects"
- elif self.app.include_objects:
- view_title = "Objects"
+ if self.app.include_objects: view_title = "Conversations & Objects"
+ elif self.app.include_objects: view_title = "Objects"
self.screen.ids.conversations_bar.title = view_title
self.update_widget()
+ self.update_incoming_status()
self.app.sideband.setstate("app.flags.unread_conversations", False)
self.app.sideband.setstate("app.flags.new_conversations", False)
self.app.sideband.setstate("wants.viewupdate.conversations", False)
+ def update_incoming_status(self, sender=None):
+ if self.ready:
+ toolbar_items = self.screen.ids.conversations_bar.ids.right_actions.children
+ if len(toolbar_items) >= 6:
+ im_button = toolbar_items[2]
+ if self.app.sideband.message_router.inbound_count() > 0: im_button.icon = "email-arrow-left-outline"
+ else: im_button.icon = "progress-download"
+
def trust_icon(self, conv):
conv_type = conv["type"]
context_dest = conv["dest"]
@@ -455,6 +464,7 @@ MDScreen:
['access-point', lambda x: root.app.announce_now_action(self)],
['webhook', lambda x: root.app.connectivity_status(self)],
['qrcode', lambda x: root.app.ingest_lxm_action(self)],
+ ['progress-download', lambda x: root.app.incoming_messages_action(self)],
['email-sync', lambda x: root.app.lxmf_sync_action(self)],
['account-plus', lambda x: root.app.new_conversation_action(self)],
]


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────